<?php

namespace app\checkin\controller;

use app\checkin\model\Setting as SettingModel;

/**
 * 规则设置管理
 * @class Setting
 * @package app\checkin\controller
 */
class Setting extends Base
{
    /**
     * 系统设置（全局）
     * @auth true
     * @menu true
     */
    public function index()
    {
        $this->title = '系统设置';
        if ($this->request->isGet()) {
            // 获取全局配置
            $config = SettingModel::getConfig(0);

            // 传递配置到视图
            $this->assign('vo', $config ? $config->toArray() : [
                'unit_minutes' => 10,
                'rounding' => 'floor',
                'timeout_minutes' => 0,
                'time_slots' => '',
                'points_expire_days' => 0,
                'voice_start' => 1,
                'voice_end' => 1,
            ]);

            // 时间段配置转为JSON字符串（用于前端编辑）
            $timeSlots = $config ? $config->time_slots : [];

            // 如果模型JSON解码后为空，尝试读取原始字段值进行修复
            if ((!is_array($timeSlots) || empty($timeSlots)) && $config) {
                try {
                    // 获取原始DB值（未经过JSON转换）
                    if (method_exists($config, 'getData')) {
                        $rawVal = $config->getData('time_slots');
                    } else {
                        $rawVal = $config->time_slots;
                    }
                    if (is_string($rawVal) && trim($rawVal) !== '') {
                        $raw = trim($rawVal);
                        $decoded = json_decode($raw, true);
                        if (!is_array($decoded)) {
                            // 尝试修复：单对象或缺少'['
                            if ($raw[0] === '{' && substr($raw, -1) === '}') {
                                $decoded = json_decode('[' . $raw . ']', true);
                            } elseif ($raw[0] !== '[' && substr($raw, -1) === ']') {
                                $decoded = json_decode('[' . $raw, true);
                            }
                        }
                        if (is_array($decoded)) {
                            $timeSlots = $decoded;
                        }
                    }
                } catch (\Throwable $e) {}
            }

            // 若为关联数组（单对象），包一层
            if (is_array($timeSlots) && !empty($timeSlots) && array_keys($timeSlots) !== range(0, count($timeSlots) - 1)) {
                if (isset($timeSlots['start']) && isset($timeSlots['end'])) {
                    $timeSlots = [$timeSlots];
                } else {
                    $timeSlots = [];
                }
            }

            $this->assign('time_slots_json', $timeSlots ? json_encode($timeSlots, JSON_UNESCAPED_UNICODE) : '');

            $this->fetch();
        } else {
            // 接收表单数据
            $unit = max(1, intval($this->request->post('unit_minutes', 10)));
            $unitPoints = max(1, intval($this->request->post('unit_points', 1)));
            $rounding = strtolower(strval($this->request->post('rounding', 'floor')));
            if (!in_array($rounding, ['floor','round','ceil'])) $rounding = 'floor';
            $timeout = max(0, intval($this->request->post('timeout_minutes', 0)));
            $expireDays = max(0, intval($this->request->post('points_expire_days', 0)));
            $voiceStart = intval($this->request->post('voice_start', 1));
            $voiceEnd = intval($this->request->post('voice_end', 1));

            // 时间段积分JSON（可为空）
            $slotsRaw = trim(strval($this->request->post('time_slots', '')));
            $slotsArr = [];
            if ($slotsRaw !== '') {
                $decoded = json_decode($slotsRaw, true);
                if ($decoded === null) {
                    // 兼容修复：单对象或缺少前置'['
                    $raw = $slotsRaw;
                    if ($raw !== '' && $raw[0] === '{' && substr($raw, -1) === '}') {
                        $decoded = json_decode('[' . $raw . ']', true);
                    } elseif ($raw !== '' && $raw[0] !== '[' && substr($raw, -1) === ']') {
                        $decoded = json_decode('[' . $raw, true);
                    }
                }
                if (!is_array($decoded)) $this->error('时间段积分配置不是有效的JSON！');

                // 修复关联数组（{"0":{...},"1":{...}}）→ 索引数组
                if (is_array($decoded) && !empty($decoded)) {
                    $keys = array_keys($decoded);
                    // 检查是否全是数字键
                    $allNumeric = true;
                    foreach ($keys as $k) {
                        if (!is_numeric($k)) {
                            $allNumeric = false;
                            break;
                        }
                    }
                    if ($allNumeric && !isset($decoded[0])) {
                        // 是关联数组，转为索引数组
                        sort($keys, SORT_NUMERIC);
                        $temp = [];
                        foreach ($keys as $k) {
                            $temp[] = $decoded[$k];
                        }
                        $decoded = $temp;
                    } elseif (array_keys($decoded) !== range(0, count($decoded) - 1)) {
                        // 单对象 → 数组
                        if (isset($decoded['start']) && isset($decoded['end'])) {
                            $decoded = [$decoded];
                        } else {
                            $this->error('时间段积分配置格式错误！');
                        }
                    }
                }

                // 基础校验与规范化
                $norm = [];
                foreach ($decoded as $i => $it) {
                    $s = isset($it['start']) ? trim(strval($it['start'])) : '';
                    $e = isset($it['end']) ? trim(strval($it['end'])) : '';
                    $p = isset($it['points_per_hour']) ? floatval($it['points_per_hour']) : 0;
                    if ($s === '' || $e === '') $this->error("第" . ($i + 1) . "条时间段 start/end 不能为空");
                    if ($p < 0) $p = 0;
                    $norm[] = ['start' => $s, 'end' => $e, 'points_per_hour' => $p];
                }
                $slotsArr = $norm;
            }

            // 保存配置（横表结构，一次性更新所有字段）
            $data = [
                'unit_minutes' => $unit,
                'unit_points' => $unitPoints,
                'rounding' => $rounding,
                'timeout_minutes' => $timeout,
                'time_slots' => $slotsArr, // 模型会自动转为JSON
                'points_expire_days' => $expireDays,
                'voice_start' => $voiceStart,
                'voice_end' => $voiceEnd,
            ];

            SettingModel::updateConfig($data, 0);
            $this->success('保存成功！');
        }
    }
}
